package org.iabako.client.ui.form.business.expense;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import org.iabako.client.tools.DefaultSuggestHandler;
import org.iabako.client.ui.form.business.SearchForm;
import org.iabako.client.ui.form.business.util.SearchActionHandler;
import org.iabako.client.ui.layout.field.CheckboxBoolean;
import org.iabako.client.ui.layout.field.InputTextDate;
import org.iabako.client.ui.layout.widget.datatable.DataTable;
import org.iabako.shared.iservice.business.ExpenseServiceAsync;
import org.iabako.shared.querydefinition.columndefinition.ExpenseColumnEnum;
import org.iabako.shared.querydefinition.dto.QueryOperatorEnum;
import org.iabako.shared.tools.GenericTools;

import java.util.Date;

/**
 * Created by jose on 04/11/14.
 */
public class ExpenseSearchForm extends Composite {

    @UiTemplate("org.iabako.client.ui.form.business.SearchForm.ui.xml")
    interface SearchFormTemplate extends UiBinder<HTMLPanel, SearchForm> {
    }

    interface ExpenseSearchTemplate extends UiBinder<HTMLPanel, ExpenseSearchForm> {
    }

    private static final SearchFormTemplate binderSearchForm = GWT.create(SearchFormTemplate.class);
    private static final ExpenseSearchTemplate binderExpenseSearchForm = GWT.create(ExpenseSearchTemplate.class);

    private final ExpenseServiceAsync expenseServiceAsync = ExpenseServiceAsync.Util.getInstance();

    @UiField
    CheckboxBoolean showExpenseOK;
    @UiField
    CheckboxBoolean showExpenseWithFutureInstallments;
    @UiField
    CheckboxBoolean showExpenseInDebt;
    @UiField
    InputTextDate expenseAfter;
    @UiField
    InputTextDate expenseBefore;

    SearchForm searchForm;

    public ExpenseSearchForm(DefaultSuggestHandler clientSuggestHandler, DataTable dataTable) {
        searchForm = new SearchForm() {
            @Override
            protected void addSpecificCriteria() {
                addExpenseCriteria();
            }

            @Override
            protected void cleanSpecificCriteria() {
                cleanExpenseCriteria();
            }
        };

        HTMLPanel searchFormPanel = binderSearchForm.createAndBindUi(searchForm);
        HTMLPanel clientSearchPanel = binderExpenseSearchForm.createAndBindUi(this);

        searchForm.addToDisclosureFormPanelContent(clientSearchPanel);
        searchForm.disclosureFormPanel.setOpen(true);
        searchForm.disclosureButton.setVisible(false);

        searchForm.setProperties(expenseServiceAsync, clientSuggestHandler, dataTable, "search_motor_expense_principal_input_title");

        initWidget(searchFormPanel);

        Date oneMonthInFuture = new Date();
        CalendarUtil.addMonthsToDate(oneMonthInFuture, 1);
        expenseBefore.setValue(oneMonthInFuture);

        setHandlers();
    }

    private void setHandlers() {
        SearchActionHandler searchActionHandler = new SearchActionHandler(searchForm);

        showExpenseOK.getCheckbox().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (showExpenseOK.getValue()) {
                    showExpenseInDebt.setValue(false);
                    showExpenseWithFutureInstallments.setValue(false);
                }
            }
        });
        showExpenseInDebt.getCheckbox().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (showExpenseInDebt.getValue()) {
                    showExpenseOK.setValue(false);
                    showExpenseWithFutureInstallments.setValue(false);
                }
            }
        });
        showExpenseWithFutureInstallments.getCheckbox().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (showExpenseWithFutureInstallments.getValue()) {
                    showExpenseOK.setValue(false);
                    showExpenseInDebt.setValue(false);
                }
            }
        });

        showExpenseOK.getCheckbox().addClickHandler(searchActionHandler);
        showExpenseInDebt.getCheckbox().addClickHandler(searchActionHandler);
        showExpenseWithFutureInstallments.getCheckbox().addClickHandler(searchActionHandler);

        expenseAfter.getInputFieldDate().addValueChangeHandler(searchActionHandler);

        expenseBefore.getInputFieldDate().addValueChangeHandler(searchActionHandler);
    }

    private void addExpenseCriteria() {
        if (showExpenseOK.getValue()) {
            searchForm.addCriteria(ExpenseColumnEnum.paymentMethod, QueryOperatorEnum.ISNOTNULL, null);
        }
        if (showExpenseInDebt.getValue()) {
            searchForm.addCriteria(ExpenseColumnEnum.paymentMethod, QueryOperatorEnum.ISNULL, null);
            searchForm.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.LESS_THAN_OR_EQUALS, GenericTools.getDateDay());
        }
        if (showExpenseWithFutureInstallments.getValue()) {
            searchForm.addCriteria(ExpenseColumnEnum.paymentMethod, QueryOperatorEnum.ISNULL, null);
            searchForm.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.GREATER_THAN, GenericTools.getDateDay());
        }
        if (!GenericTools.isEmpty(expenseAfter.getValue())) {
            searchForm.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.GREATER_THAN_OR_EQUALS, expenseAfter.getDateValue());
        }
        if (!GenericTools.isEmpty(expenseBefore.getValue())) {
            searchForm.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.LESS_THAN_OR_EQUALS, expenseBefore.getDateValue());
        }
    }

    private void cleanExpenseCriteria() {
        showExpenseOK.setValue(false);
        showExpenseInDebt.setValue(false);
        showExpenseWithFutureInstallments.setValue(false);
    }

    public void setPendingExpenseCriteria() {
        searchForm.disclosureFormPanel.setOpen(true);
        showExpenseInDebt.setValue(true);
        searchForm.addCriteria(ExpenseColumnEnum.paymentMethod, QueryOperatorEnum.ISNULL, null);
        searchForm.addCriteria(ExpenseColumnEnum.paymentDate, QueryOperatorEnum.LESS_THAN_OR_EQUALS, GenericTools.getDateDay());
    }

    public void search() {
        searchForm.search();
    }
}
